<template>
  <!-- 商品分类组件 -->
  <div class="cate_cont">
    <!-- 面包屑导航栏区域 -->
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>商品管理</el-breadcrumb-item>
      <el-breadcrumb-item>商品分类</el-breadcrumb-item>
    </el-breadcrumb>
    <!-- 卡片展示权限列表内容区域 -->
    <el-card class="box-card">
      <!-- 添加商品分类按钮 -->
      <el-row>
        <el-button type="primary" @click="addCateBut">添加分类</el-button>
      </el-row>
      <!-- 表格展示区域 -->
      <!----------------------- 重点 ------------------------>
      <!-- 第三方依赖插件vue-table-with-tree-gri，在main.js内导入：（详情见网址）https://github.com/MisterTaki/vue-table-with-tree-grid -->
      <tree-table class="el-table" :data="cateList" :columns="columns" :selection-type="false" :expand-type="false"
        show-index index-text="#" border>
        <!-- 是否有效列 -->
        <template slot="state" slot-scope="scope">
          <i class="el-icon-success" v-if="scope.row.cat_deleted === false" style="color:#67c23a;"></i>
          <i class="el-icon-error" v-else style="color:red;"></i>
        </template>
        <!-- 等级排序列 -->
        <template slot="grade" slot-scope="scope">
          <el-tag size="mini" v-if="scope.row.cat_level === 0">一级</el-tag>
          <el-tag size="mini" type="success" v-else-if="scope.row.cat_level === 1">二级</el-tag>
          <el-tag size="mini" type="warning" v-else>三级</el-tag>
        </template>
        <!-- 操作 -->
        <!-------------------------------- 重点 ---------------------------------->
        <!-- #operate="scope"（v-bind:operate="scope"） 等于：slot="operate" slot-scope="scope" ，具名插槽 -->
        <template #operate="scope">
          <el-button size="mini" type="primary" @click="alertCateFormBut(scope.row)"><i
              class="el-icon-edit"></i><span>编辑</span></el-button>
          <el-button size="mini" type="danger" @click="removeCategoryBut(scope.row.cat_id)"><i
              class="el-icon-delete"></i><span>删除</span></el-button>
        </template>
      </tree-table>
      <!-- 分页按钮区域 -->
      <el-pagination :background="true" @size-change="handleSizeChange" @current-change="handleCurrentChange"
        :current-page="gainInfo.pagenum" :page-sizes="[3, 5, 10, 15]" :page-size="gainInfo.pagesize"
        layout="total, sizes, prev, pager, next, jumper" :total="total">
      </el-pagination>

    </el-card>
    <!-- 添加分类-弹出对话框 -->
    <el-dialog title="添加分类" :close-on-click-modal="false" :visible.sync="addDialogVisible" width="50%"
      :before-close="addHandleClose">
      <el-form ref="addCateFormRef" :rules="addCateFormRules" :model="addCateForm" label-width="120px" class="add_form">
        <el-form-item label="分类名称：" prop="cat_name">
          <el-input v-model="addCateForm.cat_name"></el-input>
        </el-form-item>
        <el-form-item label="父级分类：">
          <!-- options：指定数据源；props 用来指定配置对象，...展示值等等 -->
          <!-- 问题：有些属性或方法参数，随着版本不同也不同；change-on-select在默认组件官网上的版本2.15上没有，2.62有 -->
          <el-cascader clearable change-on-select v-model="parentValue" :options="ParentCateList" :props="parentProps"
            @change="parentCateHandleChange">
          </el-cascader>
          </el-cascader>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="addHandleClose">取 消</el-button>
        <el-button type="primary" @click="addCate">确 定</el-button>
      </span>
    </el-dialog>
    <!-- 操作块-编辑按钮弹出编辑分类对话框区域 -->
    <el-dialog :close-on-click-modal="false" title="编辑分类" :visible.sync="alterDialogVisible" width="50%"
      :before-close="alterHandleClose">
      <!--重点，问题-->
      <!-- 组件的校验规则变量名不能和数据变量重名，会有奇怪的bug；el-form-item的prop="校验名"，不能和 el-input v-model="数据名" 一致；会导致赋值错误和别的奇怪错误 -->
      <el-form :model="alertCateForm" :rules="alterCateRules" ref="alterCateRef" label-width="100px" class="add_form">
        <el-form-item label="分类名称" prop="cat_name">
          <el-input v-model="alertCateForm.cat_name"></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="alterHandleClose">取 消</el-button>
        <el-button type="primary" @click="alterCateButOk">确 定</el-button>
      </span>
    </el-dialog>
  </div>

</template>

<script>
  export default {
    data() {
      return {
        // 商品分类的数据列表
        cateList: [],
        //获取商品分类的请求参数
        gainInfo: {
          type: 3,
          pagenum: 1, // 当前页数
          pagesize: 5 // 每页显示条目个数
        },
        // 商品分类总数据条数
        total: 0,
        // 第三方依赖插件vue-table-with-tree-gri的columns表格各列的配置（Columns Configs）
        columns: [
          // 第一列-列名和列值
          {
            label: '商品分类',
            prop: 'cat_name'
          },
          // 第二列-可自定义作用域模板插槽
          {
            label: '是否有效',
            type: 'template', // 定义当前列为模板列
            template: 'state', // 定义当前列使用的模板名称
            width: 100
          },
          {
            label: '等级排序',
            type: 'template',
            template: 'grade',
            width: 110
          },
          {
            label: '操作',
            type: 'template',
            template: 'operate',
            width: 215
          }
        ],
        // 添加分类-弹出的对话框显示与隐藏
        addDialogVisible: false,
        // 添加分类表单数据
        addCateForm: {
          cat_pid: 0, // 父级分类的ID
          cat_name: '', // 要添加的分类名称
          cat_level: 0 // 分类的等级，默认要添加的是一级分类
        },
        // 添加分类表单数据验证
        addCateFormRules: {
          cat_name: [{
            required: true,
            message: '请输入分类名称',
            trigger: 'blur'
          }]
        },
        // 添加分类-父级分类的数据列表
        ParentCateList: [],
        // 添加分类-选中的父级分类的选择值
        parentValue: [],
        // 添加分类-父级分类级联选择器的配置对象
        parentProps: {
          expandTrigger: 'hover', // 次级菜单的展开方式
          value: 'cat_id', // 绑定的识别属性
          label: 'cat_name', // 展示的内容
          children: 'children', // 子选项属性
        },
        // 操作块-编辑分类弹出的对话框显示与隐藏
        alterDialogVisible: false,
        // 操作块-编辑分类所需的id与名称
        alertCateForm: {
          cat_id: '',
          cat_name: ''
        },
        /*------------------------------重点，问题-------------------------------
        数据变量名，不要与校验数据的验证变量名重名，否则会可能出现bug，影响双向绑定的数据变量
        */
        // 操作块-编辑分类的验证规则
        alterCateRules: {
          cat_name: [{
            required: true,
            message: '请输入活动名称',
            trigger: 'blur'
          }]
        }

      }
    },
    created() {
      // 获取商品分类的数据列表
      this.getCateList()
    },
    methods: {
      // 获取商品分类的数据列表
      async getCateList() {
        let {
          data: res
        } = await this.$http.get('categories', {
          params: this.gainInfo
        })

        if (res.meta.status === 200) {
          // 存储商品分类列表，给总数据条数赋值
          this.cateList = res.data.result
          this.total = res.data.total
        } else {
          this.$message.error("商品分类的数据列表获取失败！")
        }

      },


      // 操作块-删除按钮-删除商品分类
      removeCategoryBut(id) {

        // 操作块-删除按钮弹出的是否删除框
        this.$confirm('此操作将永久删除该商品分类, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning',
          closeOnClickModal: false,
        }).then(async () => {
          let {
            data: res
          } = await this.$http.delete(`categories/${id}`)
          if (res.meta.status === 200) {
            this.getCateList()
            this.$message.error("此商品分类删除成功！")
          } else {
            this.$message.error("此商品分类删除失败！")
          }
        }).catch(() => {
          this.$message({
            type: 'info',
            message: '已取消删除'
          });
        });
      },


      // pageSize（每页显示条目个数） 改变时会触发
      handleSizeChange(pageSize) {
        this.gainInfo.pagesize = pageSize
        this.getCateList()
      },


      // currentPage（当前页数） 改变时会触发
      handleCurrentChange(currentPage) {
        this.gainInfo.pagenum = currentPage
        this.getCateList()
      },


      // 点击-添加分类按钮
      addCateBut() {
        // 添加分类按钮-获取父级分类的数据列表
        this.getParentCateList()
        this.addDialogVisible = true
      },


      // 添加分类按钮-弹出的对话框关闭回调
      addHandleClose() {
        this.addDialogVisible = false
        this.parentValue = []
        this.addCateForm.cat_pid = 0
        this.addCateForm.cat_level = 0
        this.$refs.addCateFormRef.resetFields()
      },


      // 添加分类按钮-获取父级分类的数据列表
      async getParentCateList() {
        let {
          data: res
        } = await this.$http.get('categories', {
          params: {
            type: 2
          }
        })

        if (res.meta.status === 200) {
          this.ParentCateList = res.data
        } else {
          this.$message.error("获取父级分类数据失败！")
        }
      },


      // 添加分类-父级分类的下拉框选择方法
      parentCateHandleChange() {
        if (this.parentValue.length > 0) {
          this.addCateForm.cat_pid = this.parentValue[this.parentValue.length - 1]
          this.addCateForm.cat_level = this.parentValue.length
        } else {
          this.addCateForm.cat_pid = 0
          this.addCateForm.cat_level = 0
        }
      },


      // 添加分类-确定按钮
      addCate() {
        this.$refs.addCateFormRef.validate(async valid => {
          if (!valid) return

          /*-------------------------------------重点----------------------------------------
          若接口文档写了：请求参数：通过 `请求体` 发送给后端
          则需要写成：('url',{ params:{ 请求参数:值 }})
          若没有写，则直接：('url',请求参数)
          */
          let {
            data: res
          } = await this.$http.post('categories', this.addCateForm)

          
          if (res.meta.status === 201) {
            this.getCateList()
            this.$message.success("此商品分类添加成功！")
          } else {
            this.$message.error("此商品分类添加失败！")
          }
          this.addHandleClose()
        })
      },


      // 操作块-点击编辑按钮
      alertCateFormBut(data) {
        // 使用 $set() 方法设置可以减少有些数据更改页面没更改的问题
        this.$set(this.alertCateForm, 'cat_id', data.cat_id)
        this.$set(this.alertCateForm, 'cat_name', data.cat_name)
        // this.alertCateForm.cat_id = data.cat_id
        // this.alertCateForm.cat_name = data.cat_name

        /*------------------------------重点，问题-----------------------------------
        对象有内存指向问题，虽然点击就会直接打印
        但是如果不依次查看打印值，而是多次点击多次打印后，最后一起查看对象的打印值
        值会都变成最后一次设置的值
        但是将对象转换成字符串打印就是没问题的，就是与每次传过来的值相同
        console.log("设置1", this.alertCateForm)
        console.log("设置2", JSON.stringify(this.alertCateForm))
        */

        this.alterDialogVisible = true
      },

      // 操作块-编辑分类的关闭回调
      alterHandleClose() {
        /*------------------------------------重点，问题---------------------------------
        如果只用组件自带的：关闭回调内  this.$refs.alterCateRef.resetFields()  
        对整个表单进行重置，将所有字段值重置为初始值并移除校验结果，
        对象的值并不会重置为最开始设置的空值，而是会变成最后传过来的值。
        所以为了避免硬性的致命bug出现。
        还得写手动清空的对象数据的代码，再结合组件的清空校验方法，同时使用
        */

        this.alterDialogVisible = false
        // 移除校验结果
        this.$refs.alterCateRef.clearValidate()
        this.alertCateForm = {}
      },


      //操作块-编辑分类的点击确定
      alterCateButOk() {
        // 对整个表单进行校验的方法，参数为一个回调函数。该回调函数会在校验结束后被调用，并传入两个参数：是否校验成功和未通过校验的字段。
        this.$refs.alterCateRef.validate(async (valid, data) => {
          if (!valid) return
          let {
            data: res
          } = await this.$http.put(`categories/${this.alertCateForm.cat_id}`, {
            cat_name: this.alertCateForm.cat_name
          })

          if (res.meta.status === 200) {
            this.getCateList()
            this.$message.success("此商品分类修改成功！")
          } else {
            this.$message.error("此商品分类修改失败！")
          }

          this.alterHandleClose()
        })


      }

    }
  }

</script>


<style lang="less" scoped>
  /* @import url('../../assets/css/Cate.less'); */

</style>
